home *** CD-ROM | disk | FTP | other *** search
/ Gold Medal Software 2 / Gold Medal Software Volume 2 (Gold Medal) (1994).iso / prog / asm_n_z.arj / XONE23.ASM < prev    next >
Assembly Source File  |  1987-10-12  |  16KB  |  753 lines

  1.     page    75,132
  2.     title    XONE - Make one ARC file from a member file
  3.  
  4. ; usage:
  5. ;       XONE inputname[.ARC] [filename] [outputname] [/R]
  6. ;
  7. ; remarks:
  8. ;    The 'inputname' is required. It defines the ARC archive
  9. ;    file which contains the member files that you want to extract.
  10. ;    The extension defaults to .ARC.
  11. ;
  12. ;    The 'filename' is optional. If omitted, all files in the
  13. ;    archive are extracted. If supplied, only that file in the
  14. ;    archive that matches the 'filename' is extracted.
  15. ;    Each extracted file is created in the ARC format using the
  16. ;    the original file name.
  17. ;
  18. ;    The 'outputname' is optional. If supplied, it defines the name
  19. ;    to be used for the extracted file. To use this operand, you must
  20. ;    also supply the 'filename' operand to extract a single file.
  21. ;
  22. ; restrictions:
  23. ;    XONE was written by Vernon Buerg and is for use without
  24. ;    restrictions. Please try to distribute this program as-is,
  25. ;    and without modification.
  26.  
  27.     .xlist
  28. print    macro    name            ; display a field
  29.     mov    dx,offset name
  30.     call    prints
  31.     endm
  32.  
  33. printl    macro    text,ctl        ; display a literal
  34.     local    txt,nxt
  35.     mov    dx,offset txt
  36.     call    prints
  37.     jmp    nxt
  38. txt    db    cr,lf,&text
  39.     ifnb    < ctl>
  40.     db    cr,lf,stopper
  41.     else
  42.     db    stopper
  43.     endif
  44. nxt    equ    $
  45.     endm
  46.  
  47.     .sall
  48.     .list
  49.  
  50. header    struc                ; archive header
  51. mbrcode db    0            ;  compression code
  52. mbrname db    13 dup (0)        ;  file name
  53. mbrsize dw    0,0            ;  file size in archive
  54. mbrdate dw    0            ;  creation date
  55. mbrtime dw    0            ;  creation time
  56. mbrcrc    dw    0            ;  cyclic redunancy check
  57. mbrlen    dw    0,0            ;  true file size, bytes
  58. header    ends
  59.  
  60. cseg    segment public para 'CODE'
  61.     assume    cs:cseg,ds:cseg,es:cseg
  62.     org    100h
  63.  
  64. xone    proc    far
  65.     jmp    start            ; do our thing
  66.  
  67. version db    cr,'   ',cr,lf          ; overlay jmp above
  68.     db    '  XONE   Make ARC file from member file(s) ',cr,lf
  69.     db    '  ----   Version 2.3 - by Vern Buerg',cr,lf,stopper
  70. usage    db    cr,lf,'  usage: XONE  archive[.ARC]  [filespec] [output] [/R]'
  71.     db    cr,lf,eof
  72.     db    stopper         ; 2.3, oops
  73.     page
  74. ;
  75. ;    return with error
  76.  
  77. error:    mov    ax,cs            ; insure seg regs
  78.     mov    ds,ax            ;  for proper exit
  79.     mov    sp,cs:stkptr
  80.     mov    errlvl,1        ; set bad return code
  81. ;    mov    dl,7            ; send bel char
  82. ;    mov    ah,2            ;  to standard output
  83. ;    int    21h
  84.  
  85. ;    set DOS error level and exit
  86.  
  87. exit:    mov    sp,cs:stkptr        ; just in case
  88.     mov    al,errlvl        ; return code
  89.     mov    ah,4ch            ; exit function
  90.     int    21h
  91.  
  92.     subttl    '--- constants, equates and work areas'
  93.     page
  94.  
  95. cr    equ    13
  96. lf    equ    10
  97. bel    equ    7
  98. tab    equ    9
  99. eof    equ    26
  100.  
  101. stopper equ    255        ; end of display line indicator
  102. arcmark equ    26        ; special archive marker
  103. xoneer    equ    9        ; highest compression code used      ;2.2
  104.  
  105. stkptr    dw    0        ; stack pointer upon entry
  106. errlvl    db    0        ; dos error level returned
  107. psp    dw    0        ; addr of psp
  108.  
  109. prompt    db    ' already exists, re-use it? (y/N) ',stopper
  110. answer    db    'n',cr,stopper
  111. found    db    0        ; indicates if found a member
  112. reuse    db    0        ; non-zero means overwrite existing file(s)
  113.  
  114. notfnd    db    cr,'  Member file not found - '
  115. member    db    13 dup (0),0    ; selected member name
  116.     db    cr,lf,stopper
  117.  
  118. archdl    dw    0        ; ARC file handle
  119. arcname db    76 dup (stopper)
  120.  
  121. outmsg    db    ' -> '          ; tells you what is being used
  122. outname db    76 dup (0)    ; output file name
  123.  
  124. ;    i/o control variables
  125.  
  126. inbufsz equ    18*1024     ; size of input buffer
  127. inadr    dw    offset inbuf    ; offset to input buffer
  128. inptr    dw    offset inbuf    ; offset to current byte
  129. insize    dw    inbufsz     ; size of input buffer
  130. inlen    dw    0        ; bytes left in buffer
  131. incurh    dw    0        ; current file offset
  132. incurl    dw    0        ;  low word
  133.  
  134. outbufsz equ    18*1024     ; size of output buffer
  135. outlen    dw    outbufsz    ; bytes empty in output buffer
  136. outadr    dw    offset outbuf    ; offset to output buffer
  137. outptr    dw    offset outbuf    ; spot for next output char
  138. outsize dw    outbufsz    ; size of output buffer
  139. outhdl    dw    0        ; output file handle
  140.  
  141. vline    db    cr,lf
  142. vstyle    db    '        '      ; compression method
  143.     db    'ed: '
  144. vname    db    12 dup (0),0
  145.     db    stopper,0
  146.  
  147. styles    db    '     sav'      ; 1 = old, no compression
  148.     db    '     Sav'      ; 2 = new, no compression
  149.     db    '    Pack'      ; 3 = dle for repeat chars
  150.     db    '  Squeez'      ; 4 = huffman encoding
  151.     db    '  crunch'      ; 5 = lz, no crc
  152.     db    '  crunch'      ; 6 = lz with crc
  153.     db    '     SEA'      ; 7 = internal SEA use
  154.     db    '  Crunch'      ; 8 = new lz with crc
  155.     db    '  squash'      ; 9 = pk squashing
  156.  
  157. wtg    dw    0        ; index into where table
  158.  
  159. where    dw    offset copy1    ; offset to routines for each type
  160.     dw    offset copy2
  161.     dw    offset unpack3
  162.     dw    offset unsqueez4
  163.     dw    offset uncrunch5
  164.     dw    offset uncrunch6
  165.     dw    offset uncrunch7
  166.     dw    offset uncrunch8
  167.     dw    offset unsquash9
  168.  
  169.     subttl    '--- mainline processing'
  170.     page
  171. ;
  172. ;    gather command line operands
  173.  
  174. start:
  175.     mov    stkptr,sp        ; save stack ptr
  176.     mov    ax,cs
  177.     mov    ds,ax            ; set local data seg
  178.     mov    cx,es
  179.     mov    psp,cx            ; save psp addr
  180.     mov    es,ax
  181.  
  182.     print    version         ; display program version
  183.  
  184.     mov    si,80h            ; get command line operand
  185.     sub    cx,cx
  186.     or    cl,byte ptr [si]    ; any operand?
  187.     jnz    parm1
  188.  
  189. parm_error:
  190.     print    usage            ; no, gotta have the ARC name
  191.     jmp    error
  192.  
  193. ;    pick off any trailing '/R' parameter
  194.  
  195. parm1:    inc    si            ; point to operand
  196.     mov    bx,si
  197.     add    bx,cx            ; point to end of command line
  198.     cmp    word ptr -2[bx],'R/'    ; is reuse specified?
  199.     je    parm1r
  200.     cmp    word ptr -2[bx],'r/'
  201.     jne    parm2
  202. parm1r: or    reuse,1         ; indicate no checking
  203.     mov    word ptr -2[bx],0d0dh    ; stop command line here
  204.     sub    cx,2            ; remove /R from command line
  205.     jle    parm_error        ; oops, something is missing
  206.  
  207. ;    get first operand - input archive file name
  208.  
  209. parm2:    lodsb                ; strip leading blanks
  210.     cmp    al,' '
  211.     loope    parm2
  212.     mov    di,offset arcname
  213.     stosb
  214.  
  215. parm3:    lodsb                ; copy ARC filename
  216.     cmp    al,cr            ; end of name?
  217.     je    parm4
  218.     cmp    al,' '                  ; delimiter?
  219.     je    parm4
  220.     cmp    al,tab            ; delimiter?
  221.     je    parm4
  222.     cmp    al,','                  ; delimiter?
  223.     je    parm4
  224.     stosb
  225.     cmp    al,'.'                  ; got extension now?
  226.     je    parm5            ; yup, that's nice
  227.     loop    parm3
  228.  
  229. parm4:    mov    ax,'A.'                 ; append default ext
  230.     stosw
  231.     mov    ax,'CR'
  232.     stosw
  233.     jmp    short parm6
  234.  
  235. ;    strip trailing blanks looking for second operand
  236.  
  237. parm5:    lodsb                ; next ext char
  238.     cmp    al,cr            ; end of it?
  239.     je    parm6
  240.     cmp    al,' '                  ; delimiter?
  241.     je    parm6
  242.     cmp    al,tab            ; another delimiter?
  243.     je    parm6
  244.     stosb                ; copy supplied extension
  245.     loop    parm5
  246. parm5a: dec    di            ; back up to end of ext
  247.  
  248. parm6:    mov    al,0            ; append asciiz stopper
  249.     stosb
  250.  
  251. ;    copy optional second (file selection) operand
  252.  
  253.     or    cx,cx            ; another operand?
  254.     jz    parm_done        ; nope, extract all files
  255.     mov    di,offset member
  256. parm7:    lodsb
  257.     cmp    al,cr            ; end of operand?
  258.     je    parm20            ; yes, done
  259.     cmp    al,' '                  ; delimiter for third operand?
  260.     je    parm10
  261.     cmp    al,tab
  262.     je    parm10
  263.     cmp    al,'a'                  ; lower case?
  264.     jb    parm8
  265.     sub    al,32
  266. parm8:    stosb
  267.     loop    parm7
  268. parm9:    mov    ax,0ff00h        ; append asciiz stopper
  269.     stosw
  270.     jmp    short parm_done
  271.  
  272. ;    get third operand, if any, as output file name
  273.  
  274. parm10: sub    cx,1            ; account for delimiter
  275.     jle    parm_done
  276.     mov    di,offset outname    ; third operand is target filename
  277. parm11: lodsb
  278.     cmp    al,' '                  ; strip leading blanks
  279.     loope    parm11
  280.     cmp    al,cr            ; ending c/r?
  281.     je    parm_done        ;  just trailing blanks, then
  282.     jcxz    parm20
  283. parm12: stosb                ; blindly copy the rest
  284.     lodsb
  285.     cmp    al,cr
  286.     loopne    parm12
  287. parm20: mov    ax,0ff00h        ; append stoppers
  288.     stosw
  289.  
  290. parm_done:                ; hope we've got everything
  291.     call    openarc         ; access the archive file
  292.     jnc    xonenext
  293.     ret
  294.  
  295.     page
  296. ;
  297. ;    process next archive header entry
  298.  
  299. xonenext:
  300.     call    gethdr            ; load next header
  301.     jnc    xone2            ; get CF at end of file, etc
  302.     jmp    exit            ; all done
  303.  
  304. xone2:    cmp    archdr.mbrcode,0    ; archive eof?
  305.     jne    xone2a            ; nope, keep on truckin
  306.  
  307.     printl    ' '                     ; blank line
  308.  
  309.     call    closarc         ; close file
  310.     cmp    member,0        ; selecting one file?
  311.     je    xone_ok         ; no, skip next
  312.     cmp    found,0         ; and did we get it?
  313.     jne    xone_ok
  314.     print    notfnd
  315.     printl    ' '
  316. xone_ok:
  317.     jmp    exit            ; depart
  318.  
  319. xone2a:
  320.     cmp    member,0        ; selecting one file?
  321.     je    xonego            ; no, skip next
  322.     mov    si,offset member    ; yes, compare names
  323.     mov    di,offset archdr.mbrname
  324.     mov    cx,13
  325. xonesel:
  326.     lodsb
  327.     cmp    al,0            ; end of name
  328.     je    xonego            ; yes, select the file
  329.     cmp    al,byte ptr [di]    ; match so far?
  330.     jne    xone_agn        ; no, skip this file
  331.     inc    di
  332.     loop    xonesel
  333.     jmp    short xonego        ; it matches
  334.  
  335. ;    the following is used to skip to the next ARC entry
  336.  
  337. xone_agn:
  338.     mov    cx,word ptr archdr.mbrsize+2
  339.     mov    dx,word ptr archdr.mbrsize
  340.     add    dx,incurl        ; add current hdr offset
  341.     adc    cx,0
  342.     add    cx,incurh
  343.     mov    ax,4200h        ; skip over file data
  344.     mov    bx,archdl
  345.     int    21h
  346.     mov    incurh,dx        ; new position
  347.     mov    incurl,ax
  348.     mov    inlen,0         ; reset read buffer
  349.     jmp    xonenext
  350.  
  351. xonego:
  352.     mov    di,offset vname     ; copy file name
  353.     mov    si,offset archdr.mbrname
  354.     mov    cx,13
  355. xone3:
  356.     lodsb
  357.     cmp    al,0            ; end of name?
  358.     je    xone4
  359.     stosb
  360.     loop    xone3
  361.     jmp    short xone5
  362. xone4:
  363.     mov    al,0            ; pad with asciiz
  364.     rep    stosb
  365.  
  366. xone5:
  367.     sub    bx,bx            ; determine style
  368.     mov    bl,archdr.mbrcode
  369.     shl    bx,1
  370.     mov    wtg,bx            ; save where-to-go offset
  371.     shl    bx,1
  372.     shl    bx,1            ; times 8 for style table
  373.     lea    si,styles-8[bx]     ; get ptr to style name
  374.     mov    di,offset vstyle
  375.     mov    cx,8
  376.     rep    movsb
  377.  
  378.     print    vline            ; display this file info
  379.     cmp    outname,0        ; specified different output?
  380.     je    xone6
  381.     print    outmsg
  382.  
  383. xone6:
  384.     call    create            ; allocate new file
  385.  
  386.     mov    bx,wtg            ; where to go
  387.     jmp    where-2[bx]        ; let 'er rip
  388.  
  389.     subttl    - Extract current member file
  390.     page
  391. ;
  392. ;    1 - straight copy of all formats
  393.  
  394. copy2:
  395. unpack3:
  396. unsqueez4:
  397. uncrunch5:
  398. uncrunch6:
  399. uncrunch7:
  400. uncrunch8:
  401. unsquash9:
  402.  
  403. copy1:
  404.     mov    si,offset newhdr    ; copy arc header first
  405.     mov    cx,hdrlen
  406. copyhdr:
  407.     lodsb
  408.     call    putc
  409.     loop    copyhdr
  410.  
  411.     mov    cx,word ptr archdr.mbrsize
  412.     mov    dx,word ptr archdr.mbrsize+2
  413. xone7:
  414.     call    getc            ; straight copy
  415.     jc    xoner1
  416.     call    putc
  417.     sub    cx,1
  418.     sbb    dx,0
  419.     or    cx,cx            ; any more bytes?
  420.     jnz    xone7            ; yup, keep on truckin'
  421.     or    dx,dx
  422.     jnz    xone7
  423.     jmp    xonemore
  424.  
  425. xoner1: printl    'Premature EOF reading '
  426.     print    vname
  427.     jmp    error
  428.  
  429. xonemore:
  430.     mov    al,arcmark        ; append normal arc mark
  431.     call    putc
  432.     mov    al,0
  433.     call    putc
  434.  
  435.     call    putblk            ; flush buffer
  436.     call    closout         ; close output
  437.     jmp    xonenext
  438.  
  439.     subttl    ' - miscellaneous subroutines'
  440.     page
  441.  
  442. openarc proc    near            ; open new archive
  443.     push    bx
  444.     mov    dx,offset arcname
  445.     mov    ax,3d02h        ; for input and output
  446.     int    21h
  447.     jc    openerr
  448.     mov    archdl,ax        ; save file handle
  449.     clc
  450.     printl    '  Using: '
  451.     print    arcname
  452.     printl    ' '
  453.     pop    bx
  454.     ret
  455. openerr:
  456.     printl    'Unable to open archive: '
  457.     print    arcname
  458.     jmp    error
  459. openarc endp
  460.  
  461.  
  462. closarc proc    near
  463.     push    bx
  464.     mov    bx,archdl        ; previous handle
  465.     or    bx,bx            ; already open?
  466.     jz    closed
  467.     mov    ah,3eh            ; yes, so close it
  468.     int    21h
  469. closed: mov    archdl,0
  470.     pop    bx
  471.     ret
  472. closarc endp
  473.  
  474. note    proc    near            ; note location of header
  475.     push    bx            ; in ARC file
  476.     sub    cx,cx
  477.     sub    dx,dx
  478.     mov    ax,4201h        ; get file pointer to EOF
  479.     mov    bx,archdl
  480.     int    21h
  481.     mov    incurh,dx        ; save hdr position
  482.     mov    incurl,ax
  483.     pop    bx
  484.     ret
  485. note    endp
  486.  
  487. create    proc    near            ; allocate new file
  488.     push    bx
  489.     mov    found,255        ; indicate member extracted
  490.     test    reuse,1         ; want to over-write?
  491.     jnz    create1         ; yup, life in the danger zone
  492.     mov    dx,offset outname    ; output specified?
  493.     cmp    byte ptr outname,0
  494.     jne    open_it
  495.     mov    dx,offset vname     ; no, use archive member file name
  496.  
  497. open_it:
  498.     mov    ax,3d00h        ; see if file already exists
  499.     int    21h
  500.     jc    create1         ; looks good so far
  501.  
  502.     mov    bx,ax            ; close found file
  503.     mov    ah,3eh
  504.     int    21h
  505.  
  506.     print    prompt            ; ask to re-use
  507.     mov    ah,0            ; get response
  508.     int    16h
  509.     mov    answer,al        ; echo response
  510.     mov    dx,offset answer
  511.     call    prints
  512.  
  513.     cmp    answer,'Y'              ; get the okay?
  514.     je    create1
  515.     cmp    answer,'y'
  516.     je    create1
  517.     jmp    xone_agn
  518.  
  519. create1:
  520.     mov    dx,offset outname    ; output specified?
  521.     cmp    byte ptr outname,0
  522.     jne    create_it
  523.     mov    dx,offset vname     ; actual file name
  524. create_it:
  525.     sub    cx,cx            ; normal attribute
  526.     mov    ah,3ch
  527.     int    21h
  528.     jc    creater         ; something failed
  529.     mov    outhdl,ax
  530.     pop    bx
  531.     ret
  532. creater:
  533.     printl    'CREATE failed - '
  534.     print    vname
  535.     jmp    error
  536. create    endp
  537.  
  538.  
  539. closout proc    near            ; close output file
  540.     mov    bx,outhdl        ; close output
  541.     or    bx,bx            ; was it open?
  542.     jz    closedout        ; no, that's funny
  543.     mov    ah,3eh
  544.     int    21h
  545. closedout:
  546.     ret
  547. closout endp
  548.  
  549. ;
  550. ;    print string like int 21h function 9
  551.  
  552. prints    proc    near            ; dx has offset to string
  553.     push    si            ;  ending in char x'ff'
  554.     push    bx
  555.     push    cx
  556.     mov    si,dx            ; pointer to text
  557.     sub    cx,cx            ; length of text
  558. ps1:    lodsb
  559.     cmp    al,stopper        ; ending stopper code?
  560.     je    ps9
  561.     inc    cx            ; no, increment length
  562.     jmp    short ps1
  563.  
  564. ps9:    mov    ah,40h            ; write to stdout
  565.     mov    bx,1
  566.     int    21h
  567.  
  568.     pop    cx            ; recover registers
  569.     pop    bx
  570.     pop    si
  571.     ret
  572. prints    endp
  573.  
  574.     subttl    ' - i/o subroutines'
  575.     page
  576.  
  577. getc    proc    near            ; return next byte in al
  578.     push    si            ;  or cf=1 for eof
  579. getc1:
  580.     sub    inlen,1         ; any left in buffer
  581.     jns    getc2            ; yes, pick it up
  582.     call    getblk
  583.     jnc    getc1
  584.     pop    si            ; return cf=1 at eof
  585.     ret
  586. getc2:
  587.     mov    si,inptr        ; offset to next byte
  588.     lodsb
  589.     mov    inptr,si
  590.     add    incurl,1        ; bump file offset
  591.     adc    incurh,0
  592.     pop    si
  593.     ret
  594. getc    endp
  595.  
  596. getblk    proc    near            ; read next block
  597.     push    ax
  598.     push    bx
  599.     push    cx
  600.     push    dx
  601.     mov    ah,3fh            ; read from handle
  602.     mov    bx,archdl        ; arc file handle
  603.     mov    cx,inbufsz        ; input buffer size
  604.     mov    dx,offset inbuf     ; offset to input buffer
  605.     mov    inptr,dx
  606.     int    21h
  607.     jc    getblkr         ; oops
  608.     or    ax,ax            ; anything read?
  609.     jnz    getblka
  610.     stc                ; no, set cf=1 for eof
  611.     jmp    short getblkx        ; and exit
  612. getblka:
  613.     mov    inlen,ax        ; return count of bytes read
  614.     clc
  615. getblkx:
  616.     pop    dx
  617.     pop    cx
  618.     pop    bx
  619.     pop    ax
  620.     ret
  621.  
  622. getblkr:
  623.     printl    "I/O error reading from "
  624.     print    arcname
  625.     jmp    error            ; gotta quit
  626. getblk    endp
  627.  
  628.     page
  629.  
  630. putc    proc    near
  631.     cmp    outlen,0        ; any room left?
  632.     jg    putc1            ; yes, stuff into buffer
  633.     call    putblk            ; no, write out buffer
  634.     jnc    putc
  635.     ret                ; return cf=1 for error
  636.  
  637. putc1:    mov    di,outptr        ; offset to next spot
  638.     stosb
  639.     mov    outptr,di        ; update ptr for next time
  640.     dec    outlen
  641.     clc                ; return cf=0 for okay
  642.     ret
  643.  
  644. putblk: push    ax            ; save regs
  645.     push    bx
  646.     push    cx
  647.     push    dx
  648.     mov    bx,outhdl        ; output file handle
  649.     mov    cx,outsize        ; buffer size
  650.     mov    ax,cx
  651.     sub    cx,outlen        ; less bytes unfilled
  652.     mov    outlen,ax        ; reset buffer size free
  653.     mov    dx,offset outbuf    ; offset to buffer
  654.     mov    outptr,dx
  655.     jcxz    putblk0         ; have nothing to write?
  656.     mov    ah,40h            ; write to a file
  657.     int    21h
  658.     jc    putcerr         ; write failed?
  659.     cmp    ax,cx            ; wrote it all?
  660.     jne    putcerr
  661. putblk0:
  662.     clc                ; clear CF error inidcator
  663.     pop    dx            ; recover regs
  664.     pop    cx
  665.     pop    bx
  666.     pop    ax
  667.     ret
  668.  
  669. putcerr:
  670.     printl    'I/O error writing to '
  671.     print    vname
  672.     jmp    error
  673. putc    endp
  674.  
  675.     subttl    '--- load next archive header'
  676.     page
  677.  
  678. gethdr    proc    near
  679.     mov    cx,128            ; gotta look for the damn thing
  680. gethdr2:
  681.     call    getc            ; get next file byte
  682.     jc    gethdrr1        ; premature eof
  683.     cmp    al,arcmark        ; start of header?
  684.     je    gethdr3         ; yup, let's start cookin
  685.     loop    gethdr2
  686. gethdrr1:
  687.     printl    "Invalid archive format!"
  688.     jmp    error
  689.  
  690. gethdr3:
  691.     call    getc            ; get version code
  692.     jc    gethdrr1
  693.     mov    archdr.mbrcode,al
  694.     cmp    al,xoneer        ; reasonable code?
  695.     ja    gethdrr1        ; nope, funny stuff
  696.     cmp    al,0            ; archive eof?
  697.     je    gethdr9         ; yup done
  698.  
  699.     mov    cx,13            ; get member name
  700.     mov    di,offset archdr.mbrname
  701. gethdr4:
  702.     call    getc
  703.     jc    gethdrr1
  704.     stosb
  705.     loop    gethdr4
  706. gethdr5:
  707.     mov    cx,10            ; length remaining
  708.     cmp    archdr.mbrcode,1    ; old format?
  709.     je    gethdr6         ; yes, it's short
  710.     mov    cl,14
  711. gethdr6:
  712.     mov    di,offset archdr.mbrsize
  713. gethdr7:
  714.     call    getc
  715.     jc    gethdrr1
  716.     stosb
  717.     loop    gethdr7
  718. gethdr8:
  719.     cmp    archdr.mbrcode,1    ; old format?
  720.     jne    gethdr9         ; if so, it's short
  721.     mov    si,offset mbrsize
  722.     mov    di,offset mbrlen
  723.     mov    cx,4
  724.     rep    movsb
  725. gethdr9:
  726.     clc
  727.     ret
  728.  
  729. gethdrr2:
  730.     printl    'Invalid archive header'
  731.     jmp    error
  732. gethdr    endp
  733.  
  734.     subttl    '--- i/o data areas'
  735.     page
  736.  
  737. xone    endp
  738.  
  739. newhdr    db    arcmark         ; starts an arc header
  740. archdr    equ    $            ; i/o area for a header
  741. hdrlen    equ    size header + 1     ; length of normal ARC header
  742.  
  743. inbuf    equ    $ + 64            ; input buffer
  744.  
  745. outbuf    equ    inbuf + inbufsz     ; output buffer
  746.  
  747. lastbyt equ    outbuf + outbufsz
  748.  
  749. pgmsize equ    (lastbyt - xone + 1024) /16    ; paragraphs in program
  750.  
  751. cseg    ends
  752.     end    xone
  753.